package org.surelink.radius.server;


import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.surelink.radius.cache.ClientCache;
import org.surelink.radius.cache.UserCache;
import org.surelink.radius.middleware.AcctMiddleware;
import org.surelink.radius.utils.AcctLogger;
import org.surelink.radius.utils.AuthLogger;
import org.tinyradius.packet.AccountingRequest;
import org.tinyradius.packet.RadiusPacket;
import org.tinyradius.util.RadiusException;
import org.tinyradius.util.RadiusServer;
import org.tinyradius.util.RadiusStat;
import org.surelink.radius.model.User;
import org.surelink.radius.model.Client;

import javax.annotation.PostConstruct;
import java.net.InetSocketAddress;
import java.util.List;

public class AcctServer extends RadiusServer {
    private static final Logger logger = Logger.getLogger(AcctServer.class);

    List<AcctMiddleware> middlewares;

    @Autowired
    private UserCache userCache;

    @Autowired
    private ClientCache clientCache;

    @Autowired
    private AcctLogger radiuslog;

    @Autowired
    private RadiusStat stat;

    private int port;

    public List<AcctMiddleware> getMiddlewares() {
        return middlewares;
    }

    public void setMiddlewares(List<AcctMiddleware> middlewares) {
        this.middlewares = middlewares;
    }

    public  AcctServer(int port){
        this.port = port;
    }

    @PostConstruct
    public void startServer(){
        setAcctPort(port);
        setRadiusStat(stat);
        start(false,true);
        logger.info("RADIUS记账服务器监听端口["+port+"]成功");

    }

    public String getSharedSecret(InetSocketAddress client) {
        Client cl = clientCache.get(client.getAddress().getHostAddress());
        if(cl==null)
            return null;
        return cl.getSecret();
    }

    public String getUserPassword(String userName) {
        return null;
    }

    public RadiusPacket accountingRequestReceived(AccountingRequest accountingRequest, InetSocketAddress client) throws RadiusException {
        radiuslog.logRequest(accountingRequest);
        RadiusPacket answer = new RadiusPacket(RadiusPacket.ACCOUNTING_RESPONSE, accountingRequest.getPacketIdentifier());
        copyProxyState(accountingRequest, answer);
        radiuslog.logResponse(accountingRequest,answer);
        return answer;
    }

    @Override
    public void afterExecute(RadiusPacket request) {

        AccountingRequest accountingRequest = (AccountingRequest) request;

        try{
            User user = userCache.get(accountingRequest.getUserName());
            for(AcctMiddleware ware:middlewares)
            {
                ware.onAcct(user,accountingRequest);
            }
        }
        catch(Exception e)
        {
            logger.error(String.format("记账中间件处理错误:%s\r\n",accountingRequest.toString()),e);
        }
    }
}
